//
//  Transaction.swift
//  bill
//
//  Created by Eudon on 2025/6/18.
//

import Foundation
import SwiftUI

// 交易数据结构
struct Transaction: Identifiable, Hashable, Codable {
    let id: UUID
    let amount: Double
    let category: String
    let date: Date
    let type: TransactionType
    let note: String?

    enum TransactionType: String, Hashable, Codable {
        case income
        case expense
    }
    
    // 实现 Hashable
    func hash(into hasher: inout Hasher) {
        hasher.combine(id)
    }
    
    static func == (lhs: Transaction, rhs: Transaction) -> Bool {
        lhs.id == rhs.id
    }
    
    // 新增：带默认id参数的init，兼容所有旧用法
    init(
        id: UUID = UUID(),
        amount: Double,
        category: String,
        date: Date,
        type: TransactionType,
        note: String?
    ) {
        self.id = id
        self.amount = amount
        self.category = category
        self.date = date
        self.type = type
        self.note = note
    }
}

// 交易数据管理类
class TransactionStore: ObservableObject {
    @Published private(set) var transactions: [Transaction] = []
    @Published var startDate: Date = Date()
    @Published var endDate: Date = Date()
    
    // 文件存储相关
    private let transactionsFileName = "transactions.json"
    private var transactionsFileURL: URL {
        let documentDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
        return documentDirectory.appendingPathComponent(transactionsFileName)
    }

    init() {
        // 设置默认日期范围为过去一个月
        endDate = Date()
        if let monthAgo = Calendar.current.date(byAdding: .month, value: -1, to: endDate) {
            startDate = monthAgo
        }
        // 优先加载本地数据
        loadTransactions()
    }
    
    // 获取日期范围内的交易
    func filteredTransactions(from: Date, to: Date) -> [Transaction] {
        let calendar = Calendar.current
        // 获取开始日期的开始时间（0:00）
        let startOfDay = calendar.startOfDay(for: from)
        // 获取结束日期的结束时间（23:59:59）
        guard let endOfDay = calendar.date(bySettingHour: 23, minute: 59, second: 59, of: to) else {
            return []
        }
        
        return transactions.filter { transaction in
            let transactionDate = transaction.date
            return transactionDate >= startOfDay && transactionDate <= endOfDay
        }.sorted { $0.date > $1.date }
    }
    
    // 获取今日交易
    func todayTransactions() -> [Transaction] {
        let calendar = Calendar.current
        let today = Date()
        let startOfDay = calendar.startOfDay(for: today)
        guard let endOfDay = calendar.date(bySettingHour: 23, minute: 59, second: 59, of: today) else {
            return []
        }
        
        return transactions.filter { transaction in
            let transactionDate = transaction.date
            return transactionDate >= startOfDay && transactionDate <= endOfDay
        }.sorted { $0.date > $1.date }
    }
    
    func addTransaction(_ transaction: Transaction) {
        DispatchQueue.main.async {
            // 插入到数组开头，确保最新的交易显示在前面
            self.transactions.insert(transaction, at: 0)
            self.saveTransactions()
            self.objectWillChange.send()
        }
    }
    
    func updateDateRange(start: Date, end: Date) {
        startDate = start
        endDate = end
        objectWillChange.send()
    }
    
    // 保存账单到本地文件
    func saveTransactions() {
        do {
            let data = try JSONEncoder().encode(transactions)
            try data.write(to: transactionsFileURL)
        } catch {
            print("保存账单数据失败: \(error)")
        }
    }
    
    // 加载账单数据（如无则生成测试数据）
    func loadTransactions() {
        do {
            let data = try Data(contentsOf: transactionsFileURL)
            let loaded = try JSONDecoder().decode([Transaction].self, from: data)
            self.transactions = loaded.sorted { $0.date > $1.date }
        } catch {
            print("加载账单数据失败: \(error)，本地无数据，保持为空")
            self.transactions = []
        }
    }
    
    func loadTestData() {
        let newTransactions = generateTestTransactions(days: 30)
        self.transactions = newTransactions.sorted { $0.date > $1.date }
        saveTransactions()
        objectWillChange.send()
    }
}

// 生成多天的测试数据
func generateTestTransactions(days: Int) -> [Transaction] {
    let categories = ["餐饮", "交通", "购物", "娱乐", "房租", "工资", "奖金"]
    var transactions: [Transaction] = []
    
    for dayOffset in 0..<days {
        let date = Calendar.current.date(byAdding: .day, value: -dayOffset, to: Date())!
        
        // 生成 3-5 条随机交易
        let transactionCount = Int.random(in: 3...5)
        for _ in 0..<transactionCount {
            let amount = Double.random(in: 10...1000)
            let category = categories.randomElement()!
            let type: Transaction.TransactionType = [.income, .expense].randomElement()!
            let note = ["", "备注1", "备注2", "备注3"].randomElement()!
            
            transactions.append(
                Transaction(
                    id: UUID(),
                    amount: amount,
                    category: category,
                    date: date,
                    type: type,
                    note: note.isEmpty ? nil : note
                )
            )
        }
    }
    
    return transactions
} 